#ifndef CHATSERVICE_H
#define CHATSERVICE_H

#include <muduo/net/TcpConnection.h>
#include <iostream>
#include <unordered_map>
#include <functional>
#include <pthread.h>
#include <mutex>
#include "json.hpp"
#include "public.hpp"
#include "UserModel.hpp"
#include "OfflineMessageModel.hpp"
#include "FriendModel.hpp"
#include "GroupModel.hpp"
using json = nlohmann::json;
using namespace std::placeholders;

// 第一个参数是 对方的TcpConnection信息，第二个参数是对方发过来的完整信息，第三个参数是 时间
using handler = std::function<void(const muduo::net::TcpConnectionPtr& conn, json& js, muduo::Timestamp)>;

class ChatService
{
public:
    static ChatService *instance();
    //登录业务
    void Login(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //注册业务
    void Register(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //客户端退出处理
    void ClinetConnetionException(const muduo::net::TcpConnectionPtr& conn);
    //服务器异常退出处理
    void reset();
    //个人聊天业务
    void OneChat(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //添加好友
    void AddFriend(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //创建群组
    void CreatGroup(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //加入群组
    void AddGroup(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //更改群成员的职位
    void ChangeRole(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);
    //群组聊天
    void GroupChat(const muduo::net::TcpConnectionPtr &conn,  json& js, muduo::Timestamp time);



    handler getHandler(int messageid);
private:
    ChatService();
private:
    // 将MegType类设置为单例模式类
    std::unordered_map<int, handler> _megHandlerMap;

    // 管理用户的链接，这样我们的服务器才知道把接受的信息发送给谁
    std::unordered_map<int, muduo::net::TcpConnectionPtr> _userConnectionMap;

    //定义一把互斥锁解决线程安全问题
    std::mutex  _mutex;

    // 操作各种数据库操作的成员变量
    UserModel _userModel;
    OfflineMessageModel _offMsgModel;
    FriendModel _friendModel;
    GroupModel  _groupModel;
};

#endif